package com.microframework.boot.datarule.controller;

import java.sql.Date;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson2.JSONObject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import com.microframework.base.core.constants.CacheConstants;
import com.microframework.base.core.datasource.annotation.Tx;
import com.microframework.base.core.util.SecurityUtils;
import com.microframework.base.core.util.UuidUtil;
import com.microframework.base.web.page.PageQuery;
import com.microframework.base.web.resp.R;
import com.microframework.boot.datarule.model.domain.Rule;
import com.microframework.boot.datarule.model.domain.RuleCol;
import com.microframework.boot.datarule.model.domain.RuleSql;
import com.microframework.boot.datarule.model.response.RuleDTO;
import com.microframework.boot.datarule.model.response.TableMetaDTO;
import com.microframework.boot.datarule.service.IRuleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/data-rule/rule")
@Tag(name = "规则管理", description = "规则管理相关接口")
public class RuleController {
	
    @Autowired
    private IRuleService ruleService;
    
    @PostMapping("/load/all")
    @Operation(summary = "一次性加载规则树型数据", description = "一次性加载规则树型数据")
    public R<List<Rule>> loadAll(@RequestBody PageQuery<Rule> pageQuery) {
        return R.ok(ruleService.loadAll(pageQuery));
    }
    
    @Operation(summary = "保存规则")
	@Parameters({ @Parameter(name = "rule", description = "规则", required = true) })
	@PostMapping("/save")
	@CachePut(value = CacheConstants.SYS_CACHES, key = "#rule.id")
	public R<Rule> save(HttpServletRequest request, @RequestBody Rule rule) {
		try {
			if (StrKit.notBlank(rule.getId())) {
				Rule checkRule=Rule.dao.findFirst("select id from "+Rule.TABLE_NAME+" where is_del=0 and code=? and id!=?",rule.getCode(),rule.getId());
				if(checkRule!=null) {
					return R.fail("规则标识重复.");
				}
				rule.setModifyTime(new Date(System.currentTimeMillis()));
				rule.setModifyUserId(SecurityUtils.getUserId());
				if (rule.update()) {
					return R.ok(rule);
				} else {
					return R.fail("更新失败.");
				}
			} else {
				Rule checkRule=Rule.dao.findFirst("select id from "+Rule.TABLE_NAME+" where is_del=0 and code=? ",rule.getCode());
				if(checkRule!=null) {
					return R.fail("规则标识重复.");
				}
				rule.setId(UuidUtil.getUUID());
				rule.setCreateTime(new Date(System.currentTimeMillis()));
				rule.setCreateUserId(SecurityUtils.getUserId());
				if (rule.save()) {
					return R.ok(rule);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}
    
	@Operation(summary = "删除规则")
	@Parameters({ @Parameter(name = "id", description = "规则id", required = true) })
	@DeleteMapping("/detain/{id}")
	@CacheEvict(value = CacheConstants.SYS_CACHES, key = "#id")
	public R<String> deleteById(@PathVariable("id") String id) {
		try {
			Rule org=new Rule();
			org.setId(id);
			org.setIsDel("1");
			if(org.update()) {
				return R.ok("删除成功.");
			}else {
				return R.fail("删除失败.");
			}
		}catch (Exception e) {
			log.error("删除异常:{}",e.getMessage());
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "保存规则SQL")
	@Parameters({ @Parameter(name = "sql", description = "规则sql内容", required = true) })
	@PostMapping("/sql/save")
	//@CachePut(value = CacheConstants.SYS_CACHES, key = "#rule.id")
	public R<RuleSql> saveSQL(HttpServletRequest request, @RequestBody RuleSql sql) {
		try {
			RuleSql checkRuleSql=RuleSql.dao.findById(sql.getId());
			if(checkRuleSql!=null) {
				sql.setModifyTime(new Date(System.currentTimeMillis()));
				sql.setModifyUserId(SecurityUtils.getUserId());
				if (sql.update()) {
					return R.ok(sql);
				} else {
					return R.fail("更新失败.");
				}
			}else {
				sql.setCreateTime(new Date(System.currentTimeMillis()));
				sql.setCreateUserId(SecurityUtils.getUserId());
				if (sql.save()) {
					return R.ok(sql);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "查询规则Sql")
	@Parameters({ @Parameter(name = "id", description = "规则id", required = true) })
	@GetMapping("/{id}/sql")
	//@CacheEvict(value = CacheConstants.SYS_CACHES, key = "#id")
	public R<RuleSql> getSqlById(@PathVariable("id") String id) {
		try {
			RuleSql ruleSql=RuleSql.dao.findById(id);
			return  R.ok(ruleSql);
		}catch (Exception e) {
			log.error("查询规则Sql异常:{}",e.getMessage());
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "执行Sql")
	@Parameters({ @Parameter(name = "id", description = "Sql id", required = true) })
	@PostMapping("/{id}/execute/sql")
	public R<TableMetaDTO> executeSql(@PathVariable("id") String id) {
		try {
			return  R.ok(ruleService.executeSql(id));
		}catch (Exception e) {
			log.error("执行Sql异常:{}",e.getMessage());
			return R.fail(e.getMessage());
		}
	}
	
    @PostMapping("/field/pages")
    @Operation(summary = "分页查询规则定义字段列表", description = "分页查询规则定义字段列表")
    public R<Page<RuleCol>> pages(@RequestBody PageQuery<RuleCol> pageQuery) {
        return R.ok(ruleService.pages(pageQuery));
    }
    
	@Operation(summary = "保存规则字段")
	@Parameters({ @Parameter(name = "ruleCol", description = "规则字段内容", required = true) })
	@PostMapping("/field/save")
	//@CachePut(value = CacheConstants.SYS_CACHES, key = "#rule.id")
	public R<RuleCol> saveRuleCol(HttpServletRequest request, @RequestBody RuleCol ruleCol) {
		try {
			if(!StrKit.isBlank(ruleCol.getId())) {
				ruleCol.setModifyTime(new Date(System.currentTimeMillis()));
				ruleCol.setModifyUserId(SecurityUtils.getUserId());
				if (ruleCol.update()) {
					return R.ok(ruleCol);
				} else {
					return R.fail("更新失败.");
				}
			}else {
				ruleCol.setId(UuidUtil.getUUID32());
				ruleCol.setCreateTime(new Date(System.currentTimeMillis()));
				ruleCol.setCreateUserId(SecurityUtils.getUserId());
				if (ruleCol.save()) {
					return R.ok(ruleCol);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "批量生成字段")
	@Parameters({ @Parameter(name = "id", description = "规则Id", required = true) })
	@PostMapping("/{id}/gen/fields")
	public R<Void> generateFields(@PathVariable("id") String id) {
		try {
			return  R.ok(ruleService.generateFields(id));
		}catch (Exception e) {
			log.error("批量生成字段异常:{}",e.getMessage());
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "删除规则字段")
	@Parameters({
	    @Parameter(name = "ids", description = "需要删除的字段Id集合，英文逗号分隔", required = true)
	})
	@DeleteMapping("/field/{ids}")
	@Tx
	public R<String> deleteFieldByIds(@PathVariable("ids") String ids) {
	    // 参数校验
	    if (StringUtils.isBlank(ids)) {
	        log.warn("删除规则字段失败：参数ids为空");
	        return R.fail("删除失败：请指定需要删除的字段ID");
	    }

	    // 转换为ID集合并去重
	    Set<String> idSet = Arrays.stream(ids.split(","))
	            .filter(StringUtils::isNotBlank)
	            .collect(Collectors.toSet());
	    
	    if (idSet.isEmpty()) {
	        log.warn("删除规则字段失败：无效的ID格式");
	        return R.fail("删除失败：无效的ID格式");
	    }

	    try {
	        int deleteCount = 0;
            for (String id : idSet) {
                if (RuleCol.dao.deleteById(id)) {
                	deleteCount++;
                }
            }
	        log.info("成功删除{}个规则字段，IDs: {}", deleteCount, idSet);
	        return R.ok(String.format("成功删除%d个字段", deleteCount));
	    } catch (Exception e) {
	        String errorMsg = String.format("删除规则字段异常（IDs: %s）: %s", idSet, e.getMessage());
	        log.error(errorMsg, e);  // 记录完整异常堆栈
	        return R.fail("删除失败：" + e.getMessage());
	    }
	}
	
	@Operation(summary = "获取列字段")
	@Parameters({
	    @Parameter(name = "ruleCode", description = "字段对应的规则标识", required = true)
	})
	@GetMapping("/{ruleCode}/columns")
	public R<RuleDTO> getColumnsByRuleCode(@PathVariable("ruleCode") String ruleCode) {
		 return R.ok(ruleService.getColumnsByRuleCode(ruleCode));
	}
	
	@Operation(summary = "根据数据规则执行保存数据")
	@Parameters({
	    @Parameter(name = "ruleCode", description = "字段对应的规则标识", required = true),
	    @Parameter(name = "params", description = "参数", required = true)
	})
	@PostMapping("/{ruleCode}/save")
	public R<RuleDTO> executeSaveByRuleCode(@PathVariable("ruleCode") String ruleCode, @RequestBody JSONObject params) {
		 return R.ok(ruleService.executeSaveByRuleCode(ruleCode,params));
	}
	
	@Operation(summary = "根据数据规则执行查询数据")
	@Parameters({
	    @Parameter(name = "ruleCode", description = "字段对应的规则标识", required = true),
	    @Parameter(name = "params", description = "参数", required = true)
	})
	@PostMapping("/{ruleCode}/query")
	public R<RuleDTO> executeQueryByRuleCode(@PathVariable("ruleCode") String ruleCode, @RequestBody JSONObject params) {
		 return R.ok();
	}
	
	@Operation(summary = "根据数据规则执行数据删除")
	@Parameters({
	    @Parameter(name = "ruleCode", description = "字段对应的规则标识", required = true),
	    @Parameter(name = "params", description = "参数", required = true)
	})
	@PostMapping("/{ruleCode}/delete")
	public R<RuleDTO> executeDeleteByRuleCode(@PathVariable("ruleCode") String ruleCode, @RequestBody JSONObject params) {
		 return R.ok();
	}
	
	@Operation(summary = "根据数据规则分页查询数据")
	@Parameters({
	    @Parameter(name = "ruleCode", description = "字段对应的规则标识", required = true),
	    @Parameter(name = "params", description = "参数", required = true)
	})
	@PostMapping("/{ruleCode}/pages")
	public R<RuleDTO> executePageByRuleCode(@PathVariable("ruleCode") String ruleCode, @RequestBody JSONObject params) {
		 return R.ok();
	}
	
}
